package com.eric.service.impl;

import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eric.domain.dto.WarehouseLayoutDTO;
import com.eric.domain.po.WarehouseLayout;
import com.eric.mapper.WarehouseLayoutMapper;
import com.eric.service.WarehouseLayoutService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class WarehouseLayoutServiceImpl extends MPJBaseServiceImpl<WarehouseLayoutMapper, WarehouseLayout> implements WarehouseLayoutService {
    @Override
    public SaResult getAllByPageService(Integer current, Integer pageSize) {
        if (current == null || current < 1) {
            current =1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10000;
        }

        MPJLambdaWrapper<WarehouseLayout>wrapper=  new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class);
        Page<WarehouseLayoutDTO>page=new Page<>(current,pageSize);
        Page<WarehouseLayoutDTO> warehouseLayoutDTOPage= selectJoinListPage(page, WarehouseLayoutDTO.class, wrapper);
        List<WarehouseLayoutDTO> records = warehouseLayoutDTOPage.getRecords();
        return SaResult.data(records);

    }

    @Override
    @Transactional
    public SaResult saveOneService(WarehouseLayoutDTO warehouseLayoutDTO) {
        WarehouseLayout warehouseLayout_in = Convert.convert(WarehouseLayout.class, warehouseLayoutDTO);
//       先判断进来的对象是否是一个一级节点
        Integer pid = warehouseLayoutDTO.getPid();
        if (pid==0){

//            一级节点，就查询数据库中有没有同样的containerName,如果有，返回错误信息
            MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getContainerName,warehouseLayoutDTO.getContainerName());
            WarehouseLayout warehouseLayout = selectJoinOne(WarehouseLayout.class, wrapper);
            if (warehouseLayout!=null){
                return SaResult.error("已存在");
            }
            else {
                boolean save = save(warehouseLayout_in);
                return save? SaResult.ok("succeed") : SaResult.error("添加失败");
            }
        }

//        不是一级节点，那么就是二级节点或者三级节点
        else {
//            查询到父节点的对象信息
            MPJLambdaWrapper<WarehouseLayout>wrapper_parent=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getId,pid);
            WarehouseLayout one = selectJoinOne(WarehouseLayout.class, wrapper_parent);


//            如果父节点的pid=0,那么就是二级节点
            if (one.getPid()==0){
//                查询同一个pid下，是否有相同的containerName
                MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                        .selectAll(WarehouseLayout.class)
                        .eq(WarehouseLayout::getContainerName,warehouseLayoutDTO.getContainerName())
                        .eq(WarehouseLayout::getPid,one.getId());
                WarehouseLayout warehouseLayout = selectJoinOne(WarehouseLayout.class, wrapper);
                if(!BeanUtil.isEmpty(warehouseLayout)){
                    return SaResult.error("已存在");
                }
                else {
//                    查询同一个pid下，是否有相同的containerNumber
                    MPJLambdaWrapper<WarehouseLayout>wrapper_number=new MPJLambdaWrapper<WarehouseLayout>()
                            .selectAll(WarehouseLayout.class)
                            .eq(WarehouseLayout::getContainerNumber,warehouseLayoutDTO.getContainerNumber())
                            .eq(WarehouseLayout::getPid,one.getId());
                    WarehouseLayout warehouseLayout_number = selectJoinOne(WarehouseLayout.class,wrapper_number);

                    if(!BeanUtil.isEmpty(warehouseLayout_number)){
                        return SaResult.error("已存在");
                    }

                    boolean save = save(warehouseLayout_in);
                    return save? SaResult.ok("succeed") : SaResult.error("添加失败");
                }
            }

//                不是二级节点，那么就是三级节点
            else {

//                是三级节点,就很简单，查询一下在同一个pid下，是否有同样的containerName和containerNumber
                //                查询同一个pid下，是否有相同的containerName
                MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                        .selectAll(WarehouseLayout.class)
                        .eq(WarehouseLayout::getContainerName,warehouseLayoutDTO.getContainerName())
                        .eq(WarehouseLayout::getPid,pid);
                WarehouseLayout warehouseLayout = selectJoinOne(WarehouseLayout.class, wrapper);
                if(!BeanUtil.isEmpty(warehouseLayout)){
                    return SaResult.error("已存在");
                }
                else {
//                    查询同一个pid下，是否有相同的containerNumber
                    MPJLambdaWrapper<WarehouseLayout>wrapper_number=new MPJLambdaWrapper<WarehouseLayout>()
                            .selectAll(WarehouseLayout.class)
                            .eq(WarehouseLayout::getContainerNumber,warehouseLayoutDTO.getContainerNumber())
                            .eq(WarehouseLayout::getPid,pid);
                    WarehouseLayout warehouseLayout_number = selectJoinOne(WarehouseLayout.class,wrapper_number);
                    if(!BeanUtil.isEmpty(warehouseLayout_number)){
                        return SaResult.error("已存在");
                    }
                    boolean save = save(warehouseLayout_in);
                    return save? SaResult.ok("succeed") : SaResult.error("添加失败");
                }
            }
        }
    }

    @Override
    public SaResult getByIdService(Integer id) {

        WarehouseLayout warehouseLayout = getById(id);
        if (warehouseLayout != null) {
            WarehouseLayoutDTO warehouseLayoutDTO = Convert.convert(WarehouseLayoutDTO.class, warehouseLayout);
            return SaResult.data(warehouseLayoutDTO);
        }

        return SaResult.error("查询失败");
    }

    @Override
    public SaResult getFirstLevelService(){
        MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getPid,0);
        List<WarehouseLayoutDTO> warehouseLayoutDTOList = selectJoinList(WarehouseLayoutDTO.class, wrapper);
        boolean empty = BeanUtil.isEmpty(warehouseLayoutDTOList);
        return empty? SaResult.error("查询失败"):SaResult.data(warehouseLayoutDTOList);

    }


    //    说名义下，这个方法，可以代替getFirstLevelService()这个方法，，只要pid=0就可以了
    @Override
    public SaResult getSecondLevelByPidService(Integer pid) {
        MPJLambdaWrapper<WarehouseLayout>wrapper =new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getPid,pid);
        List<WarehouseLayoutDTO> warehouseLayoutDTOList = selectJoinList(WarehouseLayoutDTO.class, wrapper);
        return (warehouseLayoutDTOList.isEmpty())? SaResult.error("没有子数据"):SaResult.data(warehouseLayoutDTOList);
    }

    @Override
    @Transactional
    public SaResult deleteByIdService(Integer id) {
        MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getId,id);
        WarehouseLayout one = selectJoinOne(WarehouseLayout.class, wrapper);

        if (one.getPid()==0){
//            是一级节点
            MPJLambdaWrapper<WarehouseLayout>wrapper_id_one=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getPid,one.getId());
//            获取到二级节点对象集合
            List<WarehouseLayout> warehouseLayoutList_second = selectJoinList(WarehouseLayout.class, wrapper_id_one);
//            用于存储三级节点对象
            List<WarehouseLayout>warehouseLayoutList_three=new ArrayList<>();
            for (WarehouseLayout warehouseLayout : warehouseLayoutList_second) {
                MPJLambdaWrapper<WarehouseLayout>wrapper_id_two=new MPJLambdaWrapper<WarehouseLayout>()
                        .selectAll(WarehouseLayout.class)
                        .eq(WarehouseLayout::getPid,warehouseLayout.getId());
                List<WarehouseLayout> warehouseLayoutList = selectJoinList(WarehouseLayout.class, wrapper_id_two);
                warehouseLayoutList_three.addAll(warehouseLayoutList);
            }
            warehouseLayoutList_three.addAll(warehouseLayoutList_second);
            warehouseLayoutList_three.add(one);

            boolean removed = removeByIds(warehouseLayoutList_three);
            return  removed? SaResult.ok("删除成功"):SaResult.error("删除失败");

        }

        else{
            MPJLambdaWrapper<WarehouseLayout>wrapper_pid=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getId,one.getPid());
            WarehouseLayout one_pid = selectJoinOne(WarehouseLayout.class,wrapper_pid);
            if (one_pid.getPid()==0){
                //                是二级节点
                MPJLambdaWrapper<WarehouseLayout>wrapper_three=new MPJLambdaWrapper<WarehouseLayout>()
                        .selectAll(WarehouseLayout.class)
                        .eq(WarehouseLayout::getPid,one.getId());
                List<WarehouseLayout> warehouseLayoutList = selectJoinList(WarehouseLayout.class, wrapper_three);
                warehouseLayoutList.add(one);
                boolean removed = removeByIds(warehouseLayoutList);
                return removed? SaResult.ok("删除成功"):SaResult.error("删除失败");
            }
            else {
//                是三级节点
                boolean removed = removeById(one_pid);
                return removed? SaResult.ok("删除成功"):SaResult.error("删除失败");
            }

        }
    }

    @Override
    @Transactional
    public SaResult updateByIdService(WarehouseLayoutDTO warehouseLayoutDTO) {
//        获取到前端传递来的对象的id
        Integer id = warehouseLayoutDTO.getId();
//         通过id获取到后端的一个数据对象
        MPJLambdaWrapper<WarehouseLayout>wrapper_inDb=new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getId,id);
        WarehouseLayout warehouseLayoutInDb = selectJoinOne(WarehouseLayout.class, wrapper_inDb);

        WarehouseLayoutDTO warehouseLayoutDTOInDb=BeanUtil.copyProperties(warehouseLayoutInDb, WarehouseLayoutDTO.class);

        boolean equal = ObjectUtil.equal(warehouseLayoutDTO, warehouseLayoutDTOInDb);
        if (equal){
            return SaResult.error("没有修改");
        }


//       如果pid没有变更，证明只是改了containName和description
        if (Objects.equals(warehouseLayoutDTO.getPid(), warehouseLayoutInDb.getPid())){
            WarehouseLayout warehouseLayout = BeanUtil.copyProperties(warehouseLayoutDTO, WarehouseLayout.class, "pid", "containerNumber");

            boolean b = updateById(warehouseLayout);
            return b? SaResult.ok("修改成功"):SaResult.error("修改失败");
        }
//        否则，就是pid变更了，这个就要查询一下containName是否有重复，如果有重复，就不允许修改
        else {
//            这里有一个逻辑，pid更改后，这个containerName不能和在同一个Pid下的其他containerName重复
            Integer pid = warehouseLayoutDTO.getPid();
            MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getPid,pid);
            List<WarehouseLayout> warehouseLayoutList = selectJoinList(WarehouseLayout.class, wrapper);
            for (WarehouseLayout warehouseLayout : warehouseLayoutList) {
                if (warehouseLayout.getContainerName().equals(StrUtil.trim(warehouseLayoutDTO.getContainerName()) )){
                    return SaResult.error("containerName重复");
                }
            }
            WarehouseLayout warehouseLayout = BeanUtil.copyProperties(warehouseLayoutDTO, WarehouseLayout.class);
            boolean b = updateById(warehouseLayout);
            return b? SaResult.ok("修改成功"):SaResult.error("修改失败");
        }
    }

    @Override
    public SaResult getSecondLevelService() {
//        定义一个集合，用于存储二级节点对象
        List<WarehouseLayout> secondLevelList = new ArrayList<>();
//         获取到所有数据
        List<WarehouseLayout> listInDb = list();
        for (WarehouseLayout warehouseLayout : listInDb) {
//            获取到对象的pid
            Integer pid = warehouseLayout.getPid();
            if (pid==0){
                continue;
            }
//            根据pid，获取到父节点对象
            MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getId,pid);
            WarehouseLayout warehouseLayout_parent = selectJoinOne(WarehouseLayout.class, wrapper);
            if (warehouseLayout_parent.getPid()==0){
                secondLevelList.add(warehouseLayout);
            }
        }
        List<WarehouseLayoutDTO> warehouseLayoutDTOList = BeanUtil.copyToList(secondLevelList, WarehouseLayoutDTO.class);
        return SaResult.data(warehouseLayoutDTOList);
    }

    @Override
    public SaResult getThirdLevelService() {
        //        定义一个集合，用于存储二级节点对象
        List<WarehouseLayout> thirdLevelList = new ArrayList<>();
//         获取到所有数据
        List<WarehouseLayout> listInDb = list();

        for (WarehouseLayout warehouseLayout : listInDb) {
            Integer pid_first = warehouseLayout.getPid();
            if (pid_first==0){
                continue;
            }
//            根据pid，获取到父节点对象
            MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                    .selectAll(WarehouseLayout.class)
                    .eq(WarehouseLayout::getId,pid_first);
            WarehouseLayout warehouseLayout_temp = selectJoinOne(WarehouseLayout.class, wrapper);


            Integer pid_second = warehouseLayout_temp.getPid();
            if (pid_second==0){
                continue;
            }
            else{
                thirdLevelList.add(warehouseLayout);
            }
        }
        List<WarehouseLayoutDTO> warehouseLayoutDTOList = BeanUtil.copyToList(thirdLevelList, WarehouseLayoutDTO.class);
        return SaResult.data(warehouseLayoutDTOList);
    }

    @Override
    public SaResult getOneByPidService(Integer pid) {
        MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getId,pid);
        WarehouseLayout warehouseLayout = selectJoinOne(WarehouseLayout.class, wrapper);
        WarehouseLayoutDTO warehouseLayoutDTO = BeanUtil.copyProperties(warehouseLayout, WarehouseLayoutDTO.class);
        return SaResult.data(warehouseLayoutDTO);
    }

    @Override
    public SaResult getByContainerNameService(String containerName) {

        MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
               .selectAll(WarehouseLayout.class)
               .eq(WarehouseLayout::getContainerName,containerName);
        WarehouseLayout warehouseLayout = selectJoinOne(WarehouseLayout.class, wrapper);

        return SaResult.data(BeanUtil.copyProperties(warehouseLayout, WarehouseLayoutDTO.class));
    }

    @Override
    @Transactional
    public SaResult deleteByContainerNameService(String containerName) {

        MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
                .selectAll(WarehouseLayout.class)
                .eq(WarehouseLayout::getContainerName,containerName);
        boolean remove = remove(wrapper);


        return remove ? SaResult.ok("删除成功") : SaResult.error("删除失败");
    }

    @Override
    public SaResult getAllCountsService() {
       MPJLambdaWrapper<WarehouseLayout>wrapper=new MPJLambdaWrapper<WarehouseLayout>()
               .select("count(id)");
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }
}
